#ifndef DEBUG_H_
#define DEBUG_H_

#include <Mint/Types.h>
#include "Interfaces/ITextOutput.h"
#include "Utils/String.h"

class CDebugger : public ITextOutput
{
public:
	void Initialize( void );
	void Write( char c );
	void Write( const char * message, ... );
	void DumpMemory( void * memory, Size count );
	void DumpRegisters( void * archContext );

private:
    static bool __PutCharacter( char character, void * cookie );
};

extern CDebugger * Debugger;

#if 0
#   define __FILE_OFFSET__ 20
#   define ASSERT(x) if(!(x)) Kernel::Panic( "Assert failed. %s\n\t%s:%i", #x, __FILE__ + __FILE_OFFSET__, __LINE__ )
#   define ASSERT_SZ(x,y) if(!(x)) Kernel::Panic( "Assert failed. %s\n\t%s:%i", y, __FILE__ + __FILE_OFFSET__, __LINE__ )

#   if PARANOID
#       define IF_PARANOID(x) x
#       define PARANOID_ASSERT(x) ASSERT(x)
#       define PARANOID_ASSERT_SZ(x,y) ASSERT_SZ(x,y)
#   else
#       define IF_PARANOID(x)
#       define PARANOID_ASSERT(x)
#       define PARANOID_ASSERT_SZ(x,y)
#   endif

#   define TRACE(x...)		           Debugger->Write(x)
#   define TRACE_ADDRESS(addr,size)    Debugger->DumpMemory((void*)(addr),(size))

#   if 0
#       define TRACE_CONTEXT(context)  Hardware->DumpContext((void*)(context),&sDebugger)
#   else
#       define TRACE_CONTEXT(context)
#   endif

#else

#   define ASSERT(x)
#   define ASSERT_SZ(x,y)
#   define IF_PARANOID(x) x
#   define PARANOID_ASSERT(x)
#   define PARANOID_ASSERT_SZ(x)

#   define TRACE(x...)
#   define TRACE_ADDRESS(x)
#   define TRACE_CONTEXT(x)

#endif

#define PANIC(x ...) Kernel->Panic("PANIC: " x)

#endif /*DEBUG_H_*/
